home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_c / cug172 / min.c < prev    next >
C/C++ Source or Header  |  1986-02-05  |  6KB  |  198 lines

  1. /*
  2.   HEADER: CUG     nnn.nn;
  3.   TITLE:     LEX - A Lexical Analyser Generator
  4.   VERSION:     1.0 for IBM-PC
  5.   DATE:      Jan 30, 1985
  6.   DESCRIPTION:     A Lexical Analyser Generator. From UNIX
  7.   KEYWORDS:     Lexical Analyser Generator YACC C PREP
  8.   SYSTEM:     IBM-PC and Compatiables
  9.   FILENAME:      MIN.C
  10.   WARNINGS:     This program is not for the casual user. It will
  11.          be useful primarily to expert developers.
  12.   CRC:         N/A
  13.   SEE-ALSO:     YACC and PREP
  14.   AUTHORS:     Scott Guthery 11100 leafwood lane Austin, TX 78750
  15.   COMPILERS:     DESMET-C
  16.   REFERENCES:     UNIX Systems Manuals
  17. */
  18. /*
  19.  * Copyright (c) 1978 Charles H. Forsyth
  20.  *
  21.  * Modified 02-Dec-80 Bob Denny -- Conditionalize debug code for smaller size
  22.  *  Also note other mods. Now minimization is turned on at run time by '-m'.
  23.  * More     19-Mar-82 Bob Denny -- New C library & compiler
  24.  *  This routine is unimplemented. Define MIN to turn it on. Have fun.
  25.  */
  26.  
  27. /*
  28.  * lex -- dfa minimisation routines
  29.  */
  30.  
  31. #include <stdio.h>
  32. #include "lexlex.h"
  33.  
  34. #ifdef  MIN
  35. #else
  36. /*
  37.  * Dummy routine
  38.  */
  39. dfamin()
  40. {
  41. }
  42. #endif
  43.  
  44. #ifdef  MIN
  45.  
  46. member(e, v, i)
  47. register e, *v, i;
  48. {
  49.  
  50.         while (i--)
  51.                 if (e==*v++)
  52.                         return(1);
  53.         return(0);
  54. }
  55.  
  56. extern struct set **oldpart;
  57. extern int **newpart;
  58. extern int nold, nnew;
  59.  
  60. struct  xlist {
  61.         struct  set     *x_set;
  62.         struct  trans   *x_trans;
  63.               };
  64.  
  65. xcomp(a, b)
  66. struct xlist *a, *b;
  67. {
  68.         if (a->x_trans > b->x_trans)
  69.                 return(1);
  70.         if (a->x_trans==b->x_trans)
  71.                 return(0);
  72.         return(-1);
  73. }
  74.  
  75. dfamin()
  76. {
  77.         struct xlist *temp, *tp, *xp, *zp;
  78.         struct trans *trp;
  79.         int *tp2, *ip;
  80.  
  81.         struct set *gp, **xch;
  82.         int i, j, k, niter;
  83.  
  84.         if(mflag == 0) return;          /*** NOTE ***/
  85.  
  86. #ifdef DEBUG
  87.         fprintf(lexlog, "\nDFA minimisation (%d states)\n", ndfa);
  88. #endif
  89.  
  90.         temp = lalloc(ndfa, sizeof(*temp), "minimisation");
  91.         oldpart = lalloc(ndfa, sizeof(*oldpart), "minimisation");
  92.         newpart = lalloc(ndfa*2+1, sizeof(*newpart), "minimisation");
  93.         setlist = 0;
  94. /*
  95.  * partition first into final
  96.  * states which identify different
  97.  * translations, and non-final
  98.  * states.
  99.  */
  100.         tp = temp;
  101.         for (i = 0; i < ndfa; i++, tp++) {
  102.                 tp->x_set = dfa[i].df_name;
  103.                 if (tp->x_set->s_final)
  104.                         tp->x_trans = nfa[tp->x_set->s_final].n_trans; else
  105.                         tp->x_trans = 0;
  106.         }
  107.         qsort(temp, tp-temp, sizeof(*tp), xcomp);
  108.         for (xp = temp; xp < tp; xp = zp) {
  109.                 ip = newpart;
  110.                 for (zp = xp; zp < tp && zp->x_trans==xp->x_trans; zp++)
  111.                         *ip++ = zp->x_set->s_state-dfa;
  112.                 oldpart[nold++] = newset(newpart, ip-newpart, 0);
  113.         }
  114.         free(temp);
  115. /*
  116.  * create a new partition,
  117.  * by considering each group in
  118.  * the old partition.  For each
  119.  * such group, create new subgroups
  120.  * such that two states are in the
  121.  * same subgroup iff they have
  122.  * transitions on the same set of
  123.  * characters into the same
  124.  * set of groups in the old partition.
  125.  * repeat this process until
  126.  * a fixed point is reached.
  127.  */
  128.         niter = 0;
  129.         do {
  130.                 niter++;
  131.  
  132. #ifdef DEBUG
  133.                 fprintf(lexlog, "\n%d groups in partition %d\n", nold, niter);
  134. #endif
  135.  
  136.                 for (i = 0; i < nold; i++) {
  137.                         fprintf(lexlog, "group %d: ", i);
  138.                         pset(oldpart[i], 0);
  139.                         fprintf(lexlog, "\n");
  140.                 }
  141.                 nnew = 0;
  142.                 tp2 = newpart;
  143.  
  144.                 for (i = 0; i < nold; i++) {
  145.                         gp = oldpart[i];
  146.                         for (j = 0; j < gp->s_len; j++) {
  147.                                 if (member(gp->s_els[j], newpart, tp2-newpart))
  148.                                         continue;
  149.                                 *tp2++ = gp->s_els[j];
  150.                                 for (k = 0; k < gp->s_len; k++)
  151.                                         if (k!=j &&
  152.                                             !member(gp->s_els[k], newpart,
  153.                                                 tp2-newpart) &&
  154.                                             eqstate(gp->s_els[j],gp->s_els[k]))
  155.                                                 *tp2++ = gp->s_els[k];
  156.                                 *tp2++ = -1;
  157.                         }
  158.                 }
  159.                 *tp2++ = -1;
  160.                 for (tp2 = newpart; *tp2 != -1; tp2 = ++ip) {
  161.                         for (ip = tp2; *ip != -1; ip++)
  162.                                 ;
  163.                         oldpart[nnew++] = newset(tp2, ip-tp2, 0);
  164.                 }
  165.                 i = nold; nold = nnew; nnew = i;
  166.         } while (nnew!=nold);
  167.  
  168. #ifdef DEBUG
  169.         if (ndfa==nnew)
  170.                 fprintf(lexlog, "\nno states saved by minimisation\n"); else
  171.                 fprintf(lexlog, "\n%d states saved by minimisation\n", ndfa-nnew);
  172. #endif
  173.  
  174.         free(newpart);
  175.         free(oldpart);
  176. }
  177.  
  178. eqstate(a, b)
  179. {
  180.         register struct move *dp1, *dp2;
  181.  
  182. /**  dfa vector has no element 'df_moves', transition entries have no elements
  183.         df_char nor df_set. Obviously unimplemented stuff.
  184.  
  185.         dp1 = dfa[a].df_moves;
  186.         dp2 = dfa[b].df_moves;
  187.         for (; dp1->df_set; dp1++, dp2++)
  188.                 if (dp2->df_set==0)
  189.                         return(0);
  190.                 else if (dp1->df_char != dp2->df_char ||
  191.                          dp1->df_set->s_group != dp2->df_set->s_group)
  192.                         return(0);
  193.         return(dp2->df_set==0);
  194. **/
  195.  
  196. }
  197. #endif
  198.